package com.mak001.lite.multiSkill;

import java.awt.Image;
import java.awt.Point;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;

import org.rsbuddy.tabs.Equipment;
import org.rsbuddy.tabs.Inventory;
import org.rsbuddy.widgets.Bank;

import com.rsbuddy.script.methods.Account;
import com.rsbuddy.script.methods.Calculations;
import com.rsbuddy.script.methods.Camera;
import com.rsbuddy.script.methods.Environment;
import com.rsbuddy.script.methods.Game;
import com.rsbuddy.script.methods.GroundItems;
import com.rsbuddy.script.methods.Mouse;
import com.rsbuddy.script.methods.Npcs;
import com.rsbuddy.script.methods.Objects;
import com.rsbuddy.script.methods.Players;
import com.rsbuddy.script.methods.Skills;
import com.rsbuddy.script.methods.Walking;
import com.rsbuddy.script.methods.Widgets;
import com.rsbuddy.script.util.Random;
import com.rsbuddy.script.wrappers.Area;
import com.rsbuddy.script.wrappers.GameObject;
import com.rsbuddy.script.wrappers.Item;
import com.rsbuddy.script.wrappers.Tile;

public class Methods {

	public static final Area Daemonheim = new Area(new Tile(3445, 3715),
			new Tile(3458, 3725));
	public static Area GrandExchange = new Area(new Tile(3142, 3472), new Tile(
			3184, 3508));
	public static Area Draynor = new Area(new Tile(3087, 3239), new Tile(3098,
			3247));
	public static Area Edgeville = new Area(new Tile(3088, 3485), new Tile(
			3099, 3501));
	public static Area AlKharid = new Area(new Tile(3263, 3159), new Tile(3274,
			3175));
	public static Area VarrokWest = new Area(new Tile(3163, 3426), new Tile(
			3205, 3440));
	public static Area VarrokEast = new Area(new Tile[] { new Tile(3249, 3415),
			new Tile(3257, 3415), new Tile(3258, 3425), new Tile(3249, 3425),
			new Tile(3249, 3415), });
	public static Area FaladorEast = new Area(new Tile(3001, 3352), new Tile(
			3033, 3363));
	public static Area FaladorWest = new Area(new Tile(2942, 3367), new Tile(
			2950, 3374));
	public static Area DuelArena = new Area(new Tile(3379, 3266), new Tile(
			3386, 3274));

	// complete area of Karamja island
	public static Area karamja = new Area(new Tile[] { new Tile(2963, 3170),
			new Tile(2961, 3084), new Tile(3007, 3077), new Tile(2992, 2884),
			new Tile(2751, 2872), new Tile(2739, 3127), new Tile(2695, 3145),
			new Tile(2680, 3215), new Tile(2740, 3258), new Tile(2903, 3203) });
	public static Area portBoat = new Area(new Tile(3031, 3213), new Tile(3036,
			3221));

	static int fireStaff = 1387;
	static int fireRune = 554;
	static int natureRune = 561;

	static boolean didCheck;

	public static void getItems(subScript p) {
		if (Bank.isOpen()) {
			if (Inventory.getCount() == 0
					|| Bank.depositAllExcept(p.required())) {
				int[] req = p.required();
				for (int i = 0; i < req.length; i++) {
					if (Bank.getCount(req[i]) > 0
							&& !Inventory.contains(req[i])
							&& !Equipment.containsOneOf(req[i])) {
						Bank.withdraw(req[i], 1);
					} else {
						if (!Inventory.contains(req[i])
								&& !Equipment.containsOneOf(req[i])) {
							stopSub();
						}
					}
				}
				didCheck = true;
			}
		} else {
			if (getNearestBank().contains(Players.getLocal().getLocation())) {
				Bank.open();
			} else {
				Walking.findPath(getNearestBank().getCentralTile()).traverse();
			}
		}
	}

	public static boolean hasRequired(subScript s) {
		if (didCheck == false) {
			boolean b = true;
			if (s.required() == null) {
				return true;
			} else {
				if (b == true) {
					for (int i = 0; i < s.required().length; i++) {
						if (Inventory.contains(s.required()[i])
								|| Equipment.containsOneOf(s.required()[i])) {
							b = true;
						} else {
							b = false;
						}
					}
				}
				return b;
			}
		} else {
			return true;
		}
	}

	public static boolean containsMe(Area a) {
		return a.contains(Players.getLocal().getLocation());
	}

	public static Image getImage(String url) {
		try {
			return ImageIO.read(new URL(url));
		} catch (IOException e) {
			return null;
		}
	}

	public static void stopSub() {
		Environment.takeScreenshot(true);
		MainLite.move.setEndIn(0);
	}

	public static boolean getType() {
		if (Account.isMember() && Game.isMembers()) {
			return true;
		}
		return false;
	}

	public static void switchWorld(boolean b) {
		int[] worlds;
		int[] mems = { 2, 6, 9, 12, 15, 18, 21, 22, 23, 24, 26, 27, 28, 31, 32,
				36, 39, 40, 42, 44, 45, 46, 48, 51, 52, 53, 54, 56, 58, 59, 60,
				64, 65, 66, 67, 68, 69, 70, 71, 72, 76, 77, 78, 79, 82, 83, 84,
				85, 88, 89, 91, 92, 97, 98, 99, 100, 103, 104, 112, 115, 116,
				117, 119, 121, 129, 130, 131, 132, 138, 142, 143, 144, 145,
				148, 151, 156, 157, 158, 159, 164, 166, 172 };
		int[] non = { 1, 3, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 25, 29,
				30, 33, 34, 35, 37, 38, 41, 43, 47, 49, 50, 55, 61, 62, 73, 74,
				75, 80, 81, 87, 90, 93, 102, 105, 106, 108, 118, 120, 123, 134,
				135, 141, 149, 152, 153, 154, 155, 165, 167, 169 };
		if (b == true) {
			worlds = mems;
		} else {
			worlds = non;
		}
		int world = Random.nextInt(1, worlds.length);
		Game.switchWorld(worlds[world]);

	}

	public static void move() {
		if (!getNearestBank().contains(Players.getLocal().getLocation())) {
			Walking.findPath(getNearestBank().getCentralTile()).traverse();
		} else {
			MainLite.move.setEndIn(MainLite.setEnd());
		}

	}

	public static Area getNearestBank() {
		Area nearest = null;
		for (Area a : MainLite.banks) {
			if (nearest != null) {
				if (Calculations.distanceTo(a.getCentralTile()) < Calculations
						.distanceTo(nearest.getCentralTile())) {
					nearest = a;
				}
			} else {
				nearest = a;
			}
		}
		return nearest;
	}

	public static Area getNearestBank(Tile t) {
		Area nearest = null;
		for (Area a : MainLite.banks) {
			if (nearest != null) {
				if (Calculations.distanceBetween(a.getCentralTile(), t) < Calculations
						.distanceBetween(nearest.getCentralTile(), t)) {
					nearest = a;
				}
			} else {
				nearest = a;
			}
		}
		return nearest;
	}

	public static int getBest(int[] j, int skill) {
		int p = -1;
		for (int i = 0; i < j.length; i++) {
			if (Methods.hasReqLevel(skill, i)) {
				if (bankContains(j[i]))
					p = j[i];
			}
		}
		return p;
	}

	public static boolean bankContains(int i) {
		if (MainLite.bankCache.hasItem(i)) {
			return true;
		}
		return false;
	}

	public static boolean hasReqLevel(int skill, int num) {
		if (Skills.getCurrentLevel(skill) >= getLevels(skill)[num]) {
			return true;
		}
		return false;
	}

	private static int[] getLevels(int skill) {
		if (skill == Skills.WOODCUTTING) {
			return new int[] { 1, 1, 6, 6, 21, 31, 41, 61 };
		} else if (skill == Skills.MINING) {
			return new int[] { 1, 1, 6, 21, 31, 41, 61 };
		}
		return null;
	}

	public static boolean andOr(boolean a, boolean b) {
		if (a && b == true) {
			return true;
		} else if (a || b == true) {
			return true;
		} else {
			return false;
		}
	}

	private enum stateToKar {
		CHECK, OPENFRONTFOODDOOR, PICKUPAPRON, WEARAPRON, PICKUPCHICKEN, SELL, SAIL, WALKPLANK
	}

	private static boolean isWearing = false;
	private static boolean didCheck2 = false;

	private static stateToKar getToKar() {
		int plank = 2082;
		int[] apron = { 7957, 1005 };
		int chick = 2138;
		if (didCheck2 == false) {
			return stateToKar.CHECK;
		} else {
			int foodStoreFrontDoor = 40108;
			if (Objects.getNearest(foodStoreFrontDoor) != null
					&& (Objects.getNearest(foodStoreFrontDoor).getLocation()
							.equals(new Tile(3017, 3206)) || Objects
							.getNearest(foodStoreFrontDoor).getLocation()
							.equals(new Tile(3013, 3219)))) {
				return stateToKar.OPENFRONTFOODDOOR;
			} else {
				if (Objects.getNearest(plank) != null
						&& Objects.getNearest(plank).getLocation().isOnMap()) {
					return stateToKar.WALKPLANK;
				} else {
					if (Inventory.getCount(true, 995) >= 30) {
						return stateToKar.SAIL;
					} else {
						if (Inventory.containsOneOf(apron)) {
							return stateToKar.WEARAPRON;
						} else {
							if (isWearing == false) {
								return stateToKar.PICKUPAPRON;
							} else {
								if (Inventory.contains(chick)) {
									return stateToKar.SELL;
								} else {
									return stateToKar.PICKUPCHICKEN;
								}
							}
						}
					}
				}
			}
		}
	}

	public static int prev;

	public static void toKaramja() {
		Area dock = new Area(new Tile(3017, 3211), new Tile(3053, 3246));
		Area fishStore = new Area(new Tile(3011, 3220), new Tile(3017, 3229));
		Area foodStoreFront = new Area(new Tile(3012, 3203), new Tile(3017,
				3211));
		Area foodStore = new Area(new Tile(3009, 3203), new Tile(3017, 3211));
		int foodStoreBackDoor = 2069;
		int foodStoreFrontDoor = 40108;
		int[] sailor = { 376, 377, 378 };
		int plank = 2082;
		int[] apron = { 7957, 1005 };

		while (Widgets.get(299).isValid()) {
			MainLite.sleep(500);
		}
		switch (getToKar()) {
		case CHECK:
			if (Equipment.getCount(apron) >= -1) {
				prev = Equipment.getItem(Equipment.Slot.BODY).getId();
				if (Equipment.containsOneOf(apron)) {
					isWearing = true;
				}
				didCheck2 = true;
			}
			break;
		case OPENFRONTFOODDOOR:
			if (!Players.getLocal().isMoving()) {
				if (Objects.getNearest(foodStoreFrontDoor).interact("")) {
					MainLite.sleep(500);
				} else {
					Walking.findPath(Objects.getNearest(foodStoreFrontDoor))
							.traverse();
				}
			}
			break;
		case WALKPLANK:
			Tile boat = new Tile(2956, 3143);
			if (Objects.getNearest(plank).isOnScreen() && boat.isOnScreen()) {
				if (isWearing == true) {
					if (prev != -1 || prev != 0) {
						if (Inventory.containsOneOf(prev)) {
							if (Inventory.getItem(prev).interact("Wear")) {
								isWearing = false;
								MainLite.sleep(1000);
							}
						} else {
							if (Inventory.containsOneOf(apron)) {
								isWearing = false;
							}
						}
					} else {
						isWearing = false;
					}
				} else {
					if (Inventory.getCount(apron) > 0) {
						if (Inventory.getItem(apron).interact("drop")) {
							MainLite.sleep(500);
						}
					} else if (Inventory.getCount(995) > 0) {
						if (Inventory.getItem(995).interact("drop")) {
							MainLite.sleep(500);
						}
					} else {
						if (Objects.getNearest(plank).interact("")) {
							prev = 0;
							MainLite.sleep(500);
						}
					}
				}
			} else {
				Walking.findPath(Objects.getNearest(plank)).traverse();
			}
			break;
		case WEARAPRON:
			if (Inventory.getItem(apron).interact("wear")) {
				MainLite.sleep(2000);
			}
			isWearing = true;
			break;
		case SAIL:
			if (dock.contains(Players.getLocal().getLocation())) {
				if (Npcs.getNearest(sailor).isOnScreen()) {
					if (Players.getLocal().isMoving()) {
						if (Npcs.getNearest(sailor).interact("Pay-fare")) {
							MainLite.sleep(500);
						}
					} else {
						MainLite.sleep(500);
					}
				} else {
					Walking.findPath(Npcs.getNearest(sailor)).traverse();
				}
			} else {
				Walking.findPath(dock.getCentralTile()).traverse();
			}
			break;
		case SELL:
			if (foodStoreFront.contains(Players.getLocal().getLocation())) {
				if (Widgets.get(620).isValid()) {
					if (Inventory.getItem(2138).interact("Sell 1")) {
						MainLite.sleep(1000);
					}
				} else {
					if (!Players.getLocal().isMoving()) {
						if (Npcs.getNearest(557).isOnScreen()) {
							if (Npcs.getNearest(557).interact("Trade")) {
								MainLite.sleep(1000);
							}
						}
					} else {
						MainLite.sleep(500);
					}
				}
			} else {
				if (!Players.getLocal().isMoving()) {
					Camera.turnTo(Objects.getNearest(foodStoreBackDoor));
					if (Objects.getNearest(foodStoreBackDoor).interact("")) {
						MainLite.sleep(500);
					} else {
						Walking.findPath(Objects.getNearest(foodStoreBackDoor));
					}
				}
			}
			break;
		case PICKUPCHICKEN:
			if (foodStore.contains(Players.getLocal().getLocation())) {
				if (foodStoreFront.contains(Players.getLocal().getLocation())) {
					if (!Players.getLocal().isMoving()) {
						if (Objects.getNearest(foodStoreBackDoor).interact("")) {
							MainLite.sleep(500);
						}
					}
				} else {
					if (Widgets.getComponent(228, 2).isValid()) {
						Widgets.getComponent(228, 2).click();
					} else {
						if (Objects.getNearest(15032).isOnScreen()) {
							if (Objects.getNearest(15032).interact("search")) {
								MainLite.sleep(3000);
							}
						}
					}
				}
			} else {
				Walking.findPath(foodStoreFront.getCentralTile()).traverse();
			}
			break;
		case PICKUPAPRON:
			if (fishStore.contains(Players.getLocal().getLocation())) {
				if (GroundItems.getNearest(apron) != null) {
					if (GroundItems.getNearest(apron).isOnScreen()) {
						if (!Players.getLocal().isMoving()
								&& Players.getLocal().getAnimation() == -1) {
							if (GroundItems.getNearest(apron).interact("")) {
								MainLite.sleep(500);
							}
						} else {
							MainLite.sleep(500);
						}
					} else {
						Walking.findPath(new Tile(3015, 3226)).traverse();
					}
				} else {
					MainLite.sleep(500);
				}
			} else {
				Walking.findPath(fishStore.getCentralTile()).traverse();
			}
			break;
		}
	}

	private enum stateToMain {
		GETJOB, COLLECTBANANAS, FILLCRATE, GETPAID, SAIL, WALKPLANK
	}

	private static boolean didGet = false;
	private static boolean crateFull = false;

	private static stateToMain getToMainL() {
		int plank = 2084;
		if (Inventory.getCount(true, 995) >= 30) {
			Tile boat = new Tile(3032, 3217);
			GameObject Plank = Objects.getNearest(plank);
			if (Plank != null && boat.isOnScreen()) {
				return stateToMain.WALKPLANK;
			} else {
				return stateToMain.SAIL;
			}
		} else {
			if (didGet == false) {
				return stateToMain.GETJOB;
			} else {
				if (crateFull == false) {
					if (Inventory.getCount(1963) >= 10) {
						return stateToMain.FILLCRATE;
					} else {
						return stateToMain.COLLECTBANANAS;
					}
				} else {
					return stateToMain.GETPAID;
				}
			}
		}
	}

	public static void toMainLand() {
		Area genStore = new Area(new Tile(2934, 3151), new Tile(2942, 3157));
		Area karDock = new Area(new Tile(2946, 3144), new Tile(2960, 3151));
		int customs = 380;
		while (Widgets.get(299).isValid()) {
			MainLite.sleep(500);
		}
		switch (getToMainL()) {
		case GETJOB:
			if (genStore.contains(Players.getLocal().getLocation())) {
				if (Widgets.getComponent(241, 5).isValid()) {
					if (Widgets.getComponent(241, 4).containsText(
							"your task yet?")) {
						didGet = true;
					}
					Widgets.getComponent(241, 5).click();
					MainLite.sleep(500);
				} else if (Widgets.getComponent(228, 2).isValid()) {
					Widgets.getComponent(228, 2).click();
					MainLite.sleep(500);
				} else if (Widgets.getComponent(64, 5).isValid()) {
					Widgets.getComponent(64, 5).click();
					MainLite.sleep(500);
				} else if (Widgets.getComponent(242, 6).isValid()) {
					if (Widgets.getComponent(242, 4).containsText("pay you 30")) {
						didGet = true;
					}
					Widgets.getComponent(242, 6).click();
					MainLite.sleep(500);
				} else if (Widgets.getComponent(243, 7).isValid()) {
					Widgets.getComponent(243, 7).click();
					MainLite.sleep(500);
				} else {
					if (Npcs.getNearest(379).isOnScreen()) {
						if (!Players.getLocal().isMoving()) {
							if (Npcs.getNearest(379).interact("")) {
								MainLite.sleep(500);
							}
						} else {
							MainLite.sleep(500);
						}
					} else {
						Walking.findPath(Npcs.getNearest(379)).traverse();
					}
				}
			} else {
				Walking.findPath(genStore.getCentralTile()).traverse();
			}
			break;
		case COLLECTBANANAS:
			int[] tree = { 2073, 2074, 2075, 2076, 2077 };
			GameObject Tree = Objects.getNearest(tree);
			if (Tree != null && Tree.isOnScreen()) {
				if (!Players.getLocal().isMoving()) {
					if (Objects.getNearest(tree).interact("")) {
						MainLite.sleep(750);
					}
				} else {
					MainLite.sleep(500);
				}
			} else {
				Walking.findPath(Objects.getNearest(2073)).traverse();
			}
			break;
		case FILLCRATE:
			if (Objects.getNearest(2072).isOnScreen()) {
				if (!Players.getLocal().isMoving()) {
					if (Objects.getNearest(2072).interact("Fill")) {
						MainLite.sleep(500);
						crateFull = true;
					}
				} else {
					MainLite.sleep(500);
				}
			} else {
				Walking.findPath(new Tile(2942, 3151)).traverse();
			}
			break;
		case GETPAID:
			if (genStore.contains(Players.getLocal().getLocation())) {
				if (Widgets.getComponent(64, 5).isValid()) {
					if (Widgets.getComponent(64, 5).click()) {
						MainLite.sleep(500);
					}
				} else if (Widgets.getComponent(241, 5).isValid()) {
					if (Widgets.getComponent(241, 5).click()) {
						MainLite.sleep(500);
					}
				} else {
					if (Npcs.getNearest(379).isOnScreen()) {
						if (!Players.getLocal().isMoving()) {
							if (Npcs.getNearest(379).interact("")) {
								MainLite.sleep(500);
							}
						} else {
							MainLite.sleep(500);
						}
					} else {
						Walking.findPath(Npcs.getNearest(379)).traverse();
					}
				}
			} else {
				Walking.findPath(genStore.getCentralTile()).traverse();
			}

			break;
		case SAIL:
			if (karDock.contains(Players.getLocal().getLocation())) {
				if (Npcs.getNearest(customs).isOnScreen()) {
					if (!Players.getLocal().isMoving()) {
						if (Npcs.getNearest(customs).interact("Pay-Fare")) {
							MainLite.sleep(500);
						}
					} else {
						MainLite.sleep(500);
					}
				} else {
					Walking.findPath(Npcs.getNearest(customs)).traverse();
				}
			} else {
				Walking.findPath(karDock.getCentralTile()).traverse();
			}
			break;
		case WALKPLANK:
			if (Objects.getNearest(2084) != null) {
				Objects.getNearest(2084).interact("");
				break;
			}
		}
	}

	public boolean useCabbageRecharge() {
		int[] rings = { 13560, 13561, 13562, 19760, };
		if (Equipment.containsOneOf(rings)) {
			if (Equipment.getItem(rings).interact("Run-replenish")) {
				return true;
			}
		}
		return false;
	}

	public boolean useCabbagePort() {
		int[] rings = { 13560, 13561, 13562, 19760, };
		if (Equipment.containsOneOf(rings)) {
			if (Equipment.getItem(rings).interact("Cabbage-port")) {
				return true;
			}
		}
		return false;
	}

	public static boolean containsTile(Area a, Tile t) {
		return a.contains(t);
	}

	public static boolean useItem(Item item, GameObject obj) {
		Point p = null;
		if (p == null) {
			int j = obj.getModel().getTriangles().length;
			int i = Random.nextInt(0, j - 1);
			int ps = obj.getModel().getTriangles()[i].npoints;
			int rps = Random.nextInt(0, ps - 1);
			p = new Point(obj.getModel().getTriangles()[i].xpoints[rps], obj
					.getModel().getTriangles()[i].ypoints[rps]);
		} else {
			if (Inventory.getSelectedItem().getId() == item.getId()) {
				Mouse.move(p);
				Mouse.click(true);
				return true;
			} else {
				item.interact("Use");
			}
		}
		return false;
	}

}
